Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array's length can change at any time, and data can be stored at non-contiguous locations in the array.
上述描述可以知道幾個特性:
是的,這些都是習以為常的基本知識。
C 的角度,該怎麼重新理解?與 JS 不同之處在於:
首先要知道的是,為什麼 Array 的設計是線性排列?在於記憶體的使用方式,宣告 Array 長度與型別,同時表示該 Array 將跟記憶體要求一個連續的區塊,好預留足夠的空間可以存放元素。目的是為了能夠有效運用記憶體而不浪費。
玩味的地方在於,因為 Array 的長度可能很長(意味著佔用大量的記憶體),所以使用 Array 時,傳遞該 Array 的記憶體位置(使用指標取得)遠比重新複製一個新 Array 來得快速許多,同時也能節省記憶體的消耗。這也就是為什麼 JS 中 Array 與 Object 會是 by reference,為了節省記憶體的消耗。
有了 C 的概念後,那 String 講白了就是宣告資料型別為字元的 Array 。因為長度固定,所以 C 在開發字串上蠻麻煩的。這點 Java 已經看出來,因此開發出 class String 來因應字串經常更改 Array 長度。
對於一位 JS 工程師而言,Array 的基本 CRUD 是必備的技能。這邊要提一點,部分內建函式對 Array 內的元素進行更動,此時要思考三點:
Array.prototype.shift(),所有元素的 index 都會變更,肯定會造成記憶體的消耗。Array 函式,使用越多越覺得自己很厲害,一下 Array.prototype.map()、一下 Array.prototype.filter(),說穿了,都是 for-loop 的語法糖,使用上沒有對錯,端看需求。
Array.prototype.map()、Array.prototype.filter() 等製造出新的 Array 。Array 函式的使用,盡可能 for-loop 完成。原因在於每一個 Array 內建函式幾乎都在跑 for-loop,減少使用增進效率。Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
Related Topics: Array, Two Pointer
Input: [1,8,6,2,5,4,8,3,7]
Output: 49

首先觀察題目的圖片,思考中間的數字比兩側還大時,是不是有影響到?無法判斷的情況下點擊 Hint 1,可以得知題目沒有要思考這麼細,單純比較頭尾的高度後,再藉由頭尾之間的距離算出面積,最後比較哪一組的面積最大即可。
這邊最快速的做法是 Two Pointer,一種適合用在 Array 的解題技巧,粗略來講,遍歷 Array 時,除了從頭遞增,同時從尾巴遞減,頭尾互相計算、運作後,可以得到一個最終答案。詳細操作之後討論。
JS/**
* @param {number[]} height
* @return {number}
*/
const maxArea = (height) => {
let max = 0, start = 0, end = height.length - 1;
while (start < end) {
let width = end - start;
let high = 0;
if (height[start] < height[end]) {
high = height[start];
start++;
} else{
high = height[end];
end--;
}
let temp = width * high;
if (temp > max) {
max = temp;
}
}
return max;
};
Javaclass Solution {
public int maxArea(int[] height) {
int max = 0, start = 0, end = height.length - 1;
while (start < end) {
int width = end - start;
int high = 0;
if (height[start] < height[end]) {
high = height[start];
start++;
} else {
high = height[end];
end--;
}
int temp = width * high;
if (temp > max) {
max = temp;
}
}
return max;
}
}
Cint maxArea(int *height, int heightSize)
{
int max = 0, start = 0, end = heightSize - 1;
while (start < end)
{
int width = end - start;
int high = 0;
if (height[start] < height[end])
{
high = height[start];
start++;
}
else
{
high = height[end];
end--;
}
int temp = width * high;
if (temp > max)
{
max = temp;
}
}
return max;
}
這題個人歸類在腦經急轉彎的類型,想通後三種語言的實作皆十分相似。
Array 是基本功中的基本功,JS 的工程師要補充 C 如何定義 Array 即可。至於其他解題技巧留在之後的文章內討論。